package cn.lzj.ymcc.service.impl;

import cn.lzj.ymcc.constants.RedisConstants;
import cn.lzj.ymcc.domain.CourseType;
import cn.lzj.ymcc.mapper.CourseTypeMapper;
import cn.lzj.ymcc.result.JSONResult;
import cn.lzj.ymcc.service.ICourseTypeService;
import cn.lzj.ymcc.util.AssertUtil;
import cn.lzj.ymcc.vo.CourseCrumbsVO;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import springfox.documentation.annotations.Cacheable;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author zijia.liao
 * @since 2022-07-11
 */
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {
        @Autowired
        private RedisTemplate<Object,Object> redisTemplate;

    /**
     * 课程树的逻辑
     *
     * 1.先查询出所以的课程分类数据
     * 2.把父类课程类放入新的map集合里面
     * 3.如果不是第一级别的课程分类，就是子类课程
     * 4.通过子类的pid查询出父类的id，
     * 5.根据id和pid把子类放入父类的children集合里面
     * @return
     */
    @Override
    public List<CourseType> treeData(){

        List<CourseType> courseTypeTreeData = (List<CourseType>)redisTemplate.opsForValue().get(RedisConstants.KEY_COURSE_TREEDATA);
        if(courseTypeTreeData!=null) {
            return courseTypeTreeData;
        }

        List<CourseType> courseTypesData = tree2Data();
        redisTemplate.opsForValue().set(RedisConstants.KEY_COURSE_TREEDATA, courseTypesData, 12, TimeUnit.HOURS);

        return courseTypesData;
    }

    /**
     * 面包屑逻辑的实现
     * @param id
     * @return
     */
    @Override
    public List<CourseCrumbsVO> crumbs(Long id) {
        //1.参数校验
        AssertUtil.isNotNull(id,"没有选中数据");
        //2.查询本条数据
        CourseType findById = selectById(id);
        //3.条件校验
        AssertUtil.isNotNull(findById, "没有选中课程数据");
        //4,根据id获取path
        String[] idList = selectById(id).getPath().split("\\.");//[1037,1077,xxx,xx,xx,]
        CourseType selectCoureType=null;
        //5.拿一个数组存放所以同级的课程分类
        List<CourseCrumbsVO> crumbsVOArrayList = new ArrayList<CourseCrumbsVO>();
        for (String s : idList) {
            selectCoureType=selectById(s);
            CourseCrumbsVO vo = new CourseCrumbsVO();
            vo.setOwnerProductType(selectCoureType);
            //判断是否是顶级的分类类型
            if(selectCoureType.getPid()==null||selectCoureType.getPid().equals("0")){
                vo.setOwnerProductType(selectCoureType);
            }else{
                List<CourseType> typeList = selectList(new EntityWrapper<CourseType>().eq("pid", selectCoureType.getPid()));
                vo.setOtherProductTypes(typeList);
            }
            crumbsVOArrayList.add(vo);
        }
        return crumbsVOArrayList;
    }

    public List<CourseType> tree2Data() {
        //1.先查询出所以的课程分类数据
        List<CourseType> courseTypes =selectList(null);
        HashMap<Long,CourseType> courseMap = new HashMap<>();
        for (CourseType courseType : courseTypes) {

            courseMap.put(courseType.getId(), courseType);
        }
        List<CourseType> firstcourse = new ArrayList<>();
        for (CourseType courseType : courseTypes) {
            if(courseType.getPid()==0){
                //2.把父类课程类放入新的map集合里面
                firstcourse.add(courseType);
            }else {
               //4.通过子类的pid查询出父类的id，
                CourseType parent = courseMap.get(courseType.getPid());
                //3.如果不是第一级别的课程分类，就是子类课程
                if(parent!=null){
                //5.根据id和pid把子类放入父类的children集合里面
                parent.getChildren().add(courseType);
                }
            }
        }
        return firstcourse;
    }

    @Override
    @CacheEvict(cacheNames = RedisConstants.KEY_COURSE_TREEDATA,key = "'ALL'")
    public boolean insert(CourseType entity) {
        return super.insert(entity);
    }

    @Override
    @CacheEvict(cacheNames = RedisConstants.KEY_COURSE_TREEDATA,key = "'ALL'")
    public boolean deleteById(Serializable id) {
        return super.deleteById(id);
    }

    @Override
    @CacheEvict(cacheNames = RedisConstants.KEY_COURSE_TREEDATA,key = "'ALL'")
    public boolean updateById(CourseType entity) {
        return super.updateById(entity);
    }
}
